package com.tianji.promotion.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tianji.common.domain.dto.PageDTO;
import com.tianji.promotion.domain.po.ExchangeCode;
import com.tianji.promotion.domain.query.CodeQuery;
import com.tianji.promotion.enums.ExchangeCodeStatus;
import com.tianji.promotion.mapper.ExchangeCodeMapper;
import com.tianji.promotion.service.IExchangeCodeService;
import com.tianji.promotion.utils.CodeUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import static com.tianji.common.constants.CacheConstant.EXCHANGE_CODE;

/**
 * <p>
 * 兑换码 服务实现类
 * </p>
 *
 * @author xjs
 */
@Slf4j
@Service
public class ExchangeCodeServiceImpl extends ServiceImpl<ExchangeCodeMapper, ExchangeCode> implements IExchangeCodeService {


    @Autowired
    StringRedisTemplate redisTemplate;


    @Override
    public void deleteByCouponId(Long couponId) {
        LambdaQueryWrapper<ExchangeCode> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ExchangeCode::getExchangeTargetId, couponId);
        this.remove(wrapper);
    }

    @Override
    public PageDTO<ExchangeCode> pageQuery(CodeQuery query) {
        Page<ExchangeCode> ipage = query.toMpPageDefaultSortByCreateTimeDesc();
        LambdaQueryWrapper<ExchangeCode> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(query.getCouponId() != null, ExchangeCode::getExchangeTargetId, query.getCouponId())
                .eq(query.getStatus() != null, ExchangeCode::getStatus, query.getStatus());
        IPage<ExchangeCode> page = this.page(ipage, wrapper);
        List<ExchangeCode> records = page.getRecords();
        if(CollectionUtils.isEmpty(records)){
            return PageDTO.empty(ipage);
        }
        return PageDTO.of(ipage, records);
    }

    @Override
    public void updateExchangeCode(long id, Long userId, ExchangeCodeStatus used) {
        ExchangeCode exchangeCode = new ExchangeCode();
        exchangeCode.setId((int)id);
        exchangeCode.setUserId(userId);
        exchangeCode.setStatus(used.getValue());
        this.updateById(exchangeCode);
    }

    @Override
    @Async("exchangeCodeExecutor")
    public void asyncGenerateCode(Long couponId, LocalDateTime issueEndTime, Integer totalNum) {//1000
        log.info("异步生成兑换码");
        List<ExchangeCode> codeList = new ArrayList<>(totalNum);
        // 从redis中取当前的序列号的值 1000
        // 直接incrby totalNum
        Long maxNo = redisTemplate.opsForValue().increment(EXCHANGE_CODE, totalNum);
        for(int i = maxNo.intValue(); i>=(maxNo-totalNum + 1); i--){
            String code = CodeUtil.generateCode(i, i);
            ExchangeCode exchangeCode = new ExchangeCode();
            exchangeCode.setCode(code);
            exchangeCode.setType(1);
            exchangeCode.setStatus(ExchangeCodeStatus.UNUSED.getValue());
            exchangeCode.setExpiredTime(issueEndTime);
            exchangeCode.setExchangeTargetId(couponId);
            exchangeCode.setCreateTime(LocalDateTime.now());
            exchangeCode.setUpdateTime(LocalDateTime.now());
            codeList.add(exchangeCode);
        }
        this.saveBatch(codeList);
    }
}
